using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 事件服务
/// </summary>
public static class EventService
{
    /*
         1.私有委托字典，将所有事件与对应的委托。
         2.重载添加委托函数
         3.重载移除委托函数
         4.重载触发委托函数
    */
    /// <summary>
    /// 事件字典
    /// </summary>
    /// <typeparam name="E_Event_Type">事件类型</typeparam>
    /// <typeparam name="Delegate">需要注册的委托函数</typeparam>
    /// <returns></returns>
    private static Dictionary<E_Event_Type, Delegate> EventDic = new Dictionary<E_Event_Type, Delegate>();

    private static void EventAddListenering(E_Event_Type eventType, Delegate eventCallBack)
    {
        if (!EventDic.ContainsKey(eventType))
        {
            EventDic.Add(eventType, null);
        }
        Delegate d = EventDic[eventType];
        if (d != null && d.GetType() != eventCallBack.GetType())
        {
            Debug.LogError($"当前添加的事件{eventType}的类型与应添加的类型{d.GetType()}不同");
        }
    }
    private static void EventRemoveListener(E_Event_Type eventType, Delegate eventCallBack)
    {
        if (EventDic.ContainsKey(eventType))
        {
            Delegate d = EventDic[eventType];
            if (d == null)
            {
                Debug.LogError($"事件没有对应的委托,{eventType.GetType()}为Null");
            }
            else if (d.GetType() != eventCallBack.GetType())
            {
                Debug.LogError($"移除的委托类型{d.GetType()}与事件注册的委托类型{eventCallBack.GetType()}不相同");
            }
        }
        else
        {
            Debug.LogError($"没有对应的事件键");
        }
    }
    private static void EventRemoveListenered(E_Event_Type eventType)
    {
        if (EventDic[eventType] == null)
        {
            EventDic.Remove(eventType);
        }
    }
    public static void AddEventListener(E_Event_Type eventType, EventCallBack eventCallBack)
    {
        EventAddListenering(eventType, eventCallBack);
        EventDic[eventType] = (EventCallBack)EventDic[eventType] + eventCallBack;
    }

    public static void AddEventListener<A>(E_Event_Type eventType, EventCallBack<A> eventCallBack)
    {
        EventAddListenering(eventType, eventCallBack);
        EventDic[eventType] = (EventCallBack<A>)EventDic[eventType] + eventCallBack;
    }

    public static void AddEventListener<A, B>(E_Event_Type eventType, EventCallBack<A, B> eventCallBack)
    {
        EventAddListenering(eventType, eventCallBack);
        EventDic[eventType] = (EventCallBack<A, B>)EventDic[eventType] + eventCallBack;
    }

    public static void AddEventListener<A, B, C>(E_Event_Type eventType, EventCallBack<A, B, C> eventCallBack)
    {
        EventAddListenering(eventType, eventCallBack);
        EventDic[eventType] = (EventCallBack<A, B, C>)EventDic[eventType] + eventCallBack;
    }

    public static void AddEventListener<A, B, C, D>(E_Event_Type eventType, EventCallBack<A, B, C, D> eventCallBack)
    {
        EventAddListenering(eventType, eventCallBack);
        EventDic[eventType] = (EventCallBack<A, B, C, D>)EventDic[eventType] + eventCallBack;
    }
    public static void AddEventListener<A, B, C, D, E>(E_Event_Type eventType, EventCallBack<A, B, C, D, E> eventCallBack)
    {
        EventAddListenering(eventType, eventCallBack);
        EventDic[eventType] = (EventCallBack<A, B, C, D, E>)EventDic[eventType] + eventCallBack;
    }

    public static void RemoveEventListener(E_Event_Type eventType, EventCallBack eventCallBack)
    {
        EventRemoveListener(eventType, eventCallBack);
        if (EventDic.TryGetValue(eventType, out Delegate callBack))
        {
            callBack = (EventCallBack)EventDic[eventType] - eventCallBack;
            EventDic[eventType] = callBack;
            EventRemoveListenered(eventType);
        }

    }
    public static void RemoveEventListener<A>(E_Event_Type eventType, EventCallBack<A> eventCallBack)
    {
        EventRemoveListener(eventType, eventCallBack);
        if (EventDic.TryGetValue(eventType, out Delegate callBack))
        {
            callBack = (EventCallBack<A>)EventDic[eventType] - eventCallBack;
            EventDic[eventType] = callBack;
            EventRemoveListenered(eventType);
        }

    }
    public static void RemoveEventListener<A, B>(E_Event_Type eventType, EventCallBack<A, B> eventCallBack)
    {
        EventRemoveListener(eventType, eventCallBack);
        if (EventDic.TryGetValue(eventType, out Delegate callBack))
        {
            callBack = (EventCallBack<A, B>)EventDic[eventType] - eventCallBack;
            EventDic[eventType] = callBack;
            EventRemoveListenered(eventType);
        }

    }
    public static void RemoveEventListener<A, B, C>(E_Event_Type eventType, EventCallBack<A, B, C> eventCallBack)
    {
        EventRemoveListener(eventType, eventCallBack);
        if (EventDic.TryGetValue(eventType, out Delegate callBack))
        {
            callBack = (EventCallBack<A, B, C>)EventDic[eventType] - eventCallBack;
            EventDic[eventType] = callBack;
            EventRemoveListenered(eventType);
        }

    }
    public static void RemoveEventListener<A, B, C, D>(E_Event_Type eventType, EventCallBack<A, B, C, D> eventCallBack)
    {
        EventRemoveListener(eventType, eventCallBack);
        if (EventDic.TryGetValue(eventType, out Delegate callBack))
        {
            callBack = (EventCallBack<A, B, C, D>)EventDic[eventType] - eventCallBack;
            EventDic[eventType] = callBack;
            EventRemoveListenered(eventType);
        }

    }
    public static void RemoveEventListener<A, B, C, D, E>(E_Event_Type eventType, EventCallBack<A, B, C, D, E> eventCallBack)
    {
        EventRemoveListener(eventType, eventCallBack);
        if (EventDic.TryGetValue(eventType, out Delegate callBack))
        {
            callBack = (EventCallBack<A, B, C, D, E>)EventDic[eventType] - eventCallBack;
            EventDic[eventType] = callBack;
            EventRemoveListenered(eventType);
        }

    }

    public static void EventTrigger(E_Event_Type eventType)
    {
        Delegate d;
        if (EventDic.TryGetValue(eventType, out d))
        {
            if (d is EventCallBack eventCallBack)
            {
                eventCallBack();
            }
            else
            {
                Debug.LogError($"触发的事件没有对应的委托类型{eventType}");
            }
        }
    }
    public static void EventTrigger<A>(E_Event_Type eventType, A argc)
    {
        Delegate d;
        if (EventDic.TryGetValue(eventType, out d))
        {
            if (d is EventCallBack<A> eventCallBack)
            {
                eventCallBack(argc);
            }
            else
            {
                Debug.LogError($"触发的事件没有对应的委托类型{eventType}");
            }
        }
    }
    public static void EventTrigger<A, B>(E_Event_Type eventType, A argc1, B argc2)
    {
        Delegate d;
        if (EventDic.TryGetValue(eventType, out d))
        {
            if (d is EventCallBack<A, B> eventCallBack)
            {
                eventCallBack(argc1, argc2);
            }
            else
            {
                Debug.LogError($"触发的事件没有对应的委托类型{eventType}");
            }
        }
    }
    public static void EventTrigger<A, B, C>(E_Event_Type eventType, A argc1, B argc2, C argc3)
    {
        Delegate d;
        if (EventDic.TryGetValue(eventType, out d))
        {
            if (d is EventCallBack<A, B, C> eventCallBack)
            {
                eventCallBack(argc1, argc2, argc3);
            }
            else
            {
                Debug.LogError($"触发的事件没有对应的委托类型{eventType}");
            }
        }
    }
    public static void EventTrigger<A, B, C, D>(E_Event_Type eventType, A argc1, B argc2, C argc3, D argc4)
    {
        Delegate d;
        if (EventDic.TryGetValue(eventType, out d))
        {
            if (d is EventCallBack<A, B, C, D> eventCallBack)
            {
                eventCallBack(argc1, argc2, argc3, argc4);
            }
            else
            {
                Debug.LogError($"触发的事件没有对应的委托类型{eventType}");
            }
        }
    }
    public static void EventTrigger<A, B, C, D, E>(E_Event_Type eventType, A argc1, B argc2, C argc3, D argc4, E argc5)
    {
        Delegate d;
        if (EventDic.TryGetValue(eventType, out d))
        {
            if (d is EventCallBack<A, B, C, D, E> eventCallBack)
            {
                eventCallBack(argc1, argc2, argc3, argc4, argc5);
            }
            else
            {
                Debug.LogError($"触发的事件没有对应的委托类型{eventType}");
            }
        }
    }
}
